<template>
  <div class="file-preview">
    <el-dialog
      v-model="dialogVisible"
      title="文件预览"
      :width="fileType === 'pdf' ? '700px' : '900px'"
      top="3vh"
      :before-close="handleClose"
    >
      <div class="priview-box">
        <vue-office-docx
          v-if="fileType === 'docx' && showFilePreview"
          :src="fileUrl"
          @rendered="renderedHandler"
          @error="errorHandler"
        />
        <vue-office-excel
          v-if="fileType === 'xlsx' && showFilePreview"
          :src="fileUrl"
          style="min-height: 70vh"
          @rendered="renderedHandler"
          @error="errorHandler"
        />
        <vue-office-pdf
          v-if="fileType === 'pdf' && showFilePreview"
          :src="fileUrl"
          @rendered="renderedHandler"
          @error="errorHandler"
        />
      </div>
    </el-dialog>
    <el-image-viewer
      v-if="showImageViewer && showFilePreview"
      :url-list="isString(fileUrl) ? [fileUrl] : fileUrl"
      @close="closeImgViewer"
    />
  </div>
</template>

<script setup lang="ts" name="FilePreview">
import { defineAsyncComponent, ref, watch } from "vue";
import { ElMessage, ElImageViewer, ElDialog } from 'element-plus'
import 'element-plus/es/components/message/style/css'
import 'element-plus/es/components/dialog/style/css'
import 'element-plus/es/components/image-viewer/style/css'
import { isString } from '../utils/is'

//引入相关样式
import '@vue-office/docx/lib/index.css'

//引入相关样式
import '@vue-office/excel/lib/index.css'


// 引入VueOfficeDocx组件
const VueOfficeDocx = defineAsyncComponent(() => import('@vue-office/docx'))
// 引入VueOfficeExcel组件
const VueOfficeExcel = defineAsyncComponent(() => import('@vue-office/excel'))
// 引入VueOfficePdf组件
const VueOfficePdf = defineAsyncComponent(() => import('@vue-office/pdf'))
// 定义props
const props = defineProps<{
  // string[] 仅用于 img 预览
  fileUrl: string | string[]
  fileType?: 'docx' | 'xlsx' | 'pdf' | 'img'
  showFilePreview: boolean
}>()
// 弹框关闭 回调
const handleClose = () => {
  dialogVisible.value = false
  emits('update:showFilePreview', false)
}
// 控制弹框显示
const dialogVisible = ref(false)
// 控制图片预览显示
const showImageViewer = ref(false)
// 关闭图片预览
const closeImgViewer = () => {
  showImageViewer.value = false
  emits('update:showFilePreview', false)
}

watch(
  () => props.showFilePreview,
  () => {
    if (props.showFilePreview) {
      if (props.fileType === 'img') {
        showImageViewer.value = true
      } else {
        dialogVisible.value = true
      }
    }
  }
)

interface EmitProps {
  (e: 'update:showFilePreview', type: boolean): void
}
// emit 事件
let emits = defineEmits<EmitProps>()

// 预览加载完成
const renderedHandler = () => (ElMessage.success('加载完成'))
// 预览加载失败
const errorHandler = () => {
  dialogVisible.value = false
  emits('update:showFilePreview', false)
  ElMessage.error('加载失败，请稍后再试')
}
</script>
<style scoped lang="scss">
.file-preview {
  .priview-box {
    width: 100%;
  }
  :deep(.el-dialog__body) {
    padding: 20px 30px 30px;
  }
  :deep(.x-spreadsheet-sheet) {
    width: 100% !important;
  }
}
</style>
